﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Navigation;

namespace WebFlipScreenSaver.Controls
{
	/// <summary>
	/// Interaction logic for BindableWebBrowser.xaml
	/// </summary>
	public partial class BindableWebBrowser : UserControl
	{
		private const string _SkipSourceChange = "Skip";

		public BindableWebBrowser()
		{
			InitializeComponent();

			CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseBack, BrowseBack, CanBrowseBack));
			CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseForward, BrowseForward, CanBrowseForward));
			CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, Refresh, TrueCanExecute));
			
			browser.LoadCompleted += new LoadCompletedEventHandler(browser_LoadCompleted);
		}

		void browser_LoadCompleted(object sender, NavigationEventArgs e)
		{
			browser.SuppressScriptErrors(true);
			ZoomPropertyChanged(new DependencyPropertyChangedEventArgs(ZoomProperty, 100, Zoom));
		}


		public string BindableSource
		{
			get { return (string)GetValue(BindableSourceProperty); }
			set { SetValue(BindableSourceProperty, value); }
		}

		public bool ShouldHandleNavigated
		{
			get { return (bool)GetValue(ShouldHandleNavigatedProperty); }
			set { SetValue(ShouldHandleNavigatedProperty, value); }
		}

		public static readonly DependencyProperty BindableSourceProperty =
														DependencyProperty.RegisterAttached(
																"BindableSource",
																typeof(string),
																typeof(BindableWebBrowser));

		public static readonly DependencyProperty ShouldHandleNavigatedProperty =
														DependencyProperty.RegisterAttached(
																"ShouldHandleNavigated",
																typeof(Boolean),
																typeof(BindableWebBrowser));



		#region public int ZoomProperty

		/// <summary>
		/// Identifies the ZoomProperty dependency property.
		/// </summary>
		public static DependencyProperty ZoomProperty =
			DependencyProperty.RegisterAttached("Zoom", typeof(int), typeof(BindableWebBrowser));

		public int Zoom
		{
			get { return (int)GetValue(ZoomProperty); }
			set { SetValue(ZoomProperty, value); }
		}


		public void ZoomPropertyChanged(DependencyPropertyChangedEventArgs e)
		{
			if (browser != null)
			{
				int zoomPercent = (int)e.NewValue;
				browser.OpticalZoom(zoomPercent);
			}
		}

		#endregion public int ZoomProperty

		#region public bool FireRefresh

		/// <summary>
		/// Identifies the FireRefresh dependency property.
		/// </summary>
		public static DependencyProperty FireRefreshProperty =
			DependencyProperty.Register("FireRefresh", typeof (bool), typeof (BindableWebBrowser), null);

		/// <summary>
		/// 
		/// </summary>
		public bool FireRefresh
		{
			get { return (bool) GetValue(FireRefreshProperty); }

			set { SetValue(FireRefreshProperty, value); }
		}

		#endregion public bool FireRefresh

		protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
		{
			base.OnPropertyChanged(e);

			if (e.Property == BindableSourceProperty)
			{
				BindableSourcePropertyChanged(e);
			}
			else if (e.Property == ShouldHandleNavigatedProperty)
			{
				ShouldHandleNavigatedPropertyChanged(e);
			}
			else if (e.Property == ZoomProperty)
			{
				ZoomPropertyChanged(e);
			}
			else if (e.Property == FireRefreshProperty)
			{
				try
				{
					if(browser.IsLoaded)
						browser.Refresh();
				}
				catch (Exception)
				{

				}
				
			}
		}

		public void ShouldHandleNavigatedPropertyChanged(DependencyPropertyChangedEventArgs e)
		{
			if (browser != null)
			{
				if ((bool)e.NewValue)
				{
					browser.Navigated += new NavigatedEventHandler(Browser_Navigated);
				}
				else
				{
					browser.Navigated -= new NavigatedEventHandler(Browser_Navigated);
				}
			}
		}

		public void BindableSourcePropertyChanged(DependencyPropertyChangedEventArgs e)
		{
			if (browser != null)
			{
				string uri = e.NewValue as string;
				if (!_SkipSourceChange.Equals(browser.Tag))
				{
					browser.Source = !string.IsNullOrEmpty(uri) ? new Uri(uri) : null;

					//Or, if you prefer...
					//webBrowser.NavigateToString((string)e.NewValue); 
				}
			}
		}

		private void Browser_Navigated(object sender, NavigationEventArgs e)
		{
			WebBrowser browser = sender as WebBrowser;
			if (browser != null)
			{
				if (BindableSource != e.Uri.ToString())
				{
					browser.Tag = _SkipSourceChange;
					this.BindableSource = browser.Source.AbsoluteUri;
					browser.Tag = null;
				}
			}
		}

		private void CanBrowseBack(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = browser.CanGoBack;
		}

		private void BrowseBack(object sender, ExecutedRoutedEventArgs e)
		{
			browser.GoBack();
		}

		private void CanBrowseForward(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = browser.CanGoForward;
		}

		private void BrowseForward(object sender, ExecutedRoutedEventArgs e)
		{
			browser.GoForward();
		}

		private void TrueCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; }

		private void Refresh(object sender, ExecutedRoutedEventArgs e)
		{
			try { browser.Refresh(); }
			catch (Exception ex) { Console.WriteLine(ex.ToString()); }
		}

		public WebBrowser WebBrowser()
		{
			return browser;
		}
	}

}
